{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using backend: pytorch\n"
     ]
    }
   ],
   "source": [
    "import dgl.nn as dglnn\n",
    "from dgl import from_networkx\n",
    "import torch.nn as nn\n",
    "import torch as th\n",
    "import torch.nn.functional as F\n",
    "import dgl.function as fn\n",
    "import networkx as nx\n",
    "import pandas as pd\n",
    "import socket\n",
    "import struct\n",
    "import random\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.model_selection import train_test_split\n",
    "import category_encoders as ce\n",
    "from sklearn.decomposition import PCA\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = pd.read_csv('ton_iot.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "scanning      7140161\n",
       "ddos          6165008\n",
       "dos           3375328\n",
       "xss           2108944\n",
       "password      1365958\n",
       "normal         788599\n",
       "backdoor       508116\n",
       "injection      452659\n",
       "ransomware      72805\n",
       "mitm             1052\n",
       "Name: type, dtype: int64"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.type.value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "#df = data.drop(data[(data.type == 'mitm') & (data.type > 'ransomware')].index)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "#mitm = data[data['type'] == 'mitm']\n",
    "#ransomware = data[data['type'] == 'ransomware']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = data.sample(frac=0.1,random_state = 123)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "#data = pd.concat([df,mitm,ransomware], axis=0, ignore_index=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ts</th>\n",
       "      <th>src_ip</th>\n",
       "      <th>src_port</th>\n",
       "      <th>dst_ip</th>\n",
       "      <th>dst_port</th>\n",
       "      <th>proto</th>\n",
       "      <th>service</th>\n",
       "      <th>duration</th>\n",
       "      <th>src_bytes</th>\n",
       "      <th>dst_bytes</th>\n",
       "      <th>...</th>\n",
       "      <th>http_response_body_len</th>\n",
       "      <th>http_status_code</th>\n",
       "      <th>http_user_agent</th>\n",
       "      <th>http_orig_mime_types</th>\n",
       "      <th>http_resp_mime_types</th>\n",
       "      <th>weird_name</th>\n",
       "      <th>weird_addl</th>\n",
       "      <th>weird_notice</th>\n",
       "      <th>label</th>\n",
       "      <th>type</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>11296090</th>\n",
       "      <td>1556027596</td>\n",
       "      <td>192.168.1.32</td>\n",
       "      <td>64386.0</td>\n",
       "      <td>192.168.35.70</td>\n",
       "      <td>80.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1.0</td>\n",
       "      <td>scanning</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4548155</th>\n",
       "      <td>1556226499</td>\n",
       "      <td>192.168.1.31</td>\n",
       "      <td>54888.0</td>\n",
       "      <td>192.168.1.190</td>\n",
       "      <td>80.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>0.000011</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1.0</td>\n",
       "      <td>ddos</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21842540</th>\n",
       "      <td>1556221235</td>\n",
       "      <td>192.168.1.31</td>\n",
       "      <td>55574.0</td>\n",
       "      <td>192.168.1.152</td>\n",
       "      <td>80.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>41.465948</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1.0</td>\n",
       "      <td>ddos</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17338199</th>\n",
       "      <td>1556367296</td>\n",
       "      <td>192.168.1.35</td>\n",
       "      <td>44801.0</td>\n",
       "      <td>192.168.1.1</td>\n",
       "      <td>53.0</td>\n",
       "      <td>udp</td>\n",
       "      <td>dns</td>\n",
       "      <td>0.030778</td>\n",
       "      <td>80.0</td>\n",
       "      <td>112.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1.0</td>\n",
       "      <td>xss</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10681504</th>\n",
       "      <td>1556310888</td>\n",
       "      <td>192.168.1.32</td>\n",
       "      <td>43152.0</td>\n",
       "      <td>192.168.1.190</td>\n",
       "      <td>80.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>http</td>\n",
       "      <td>0.002832</td>\n",
       "      <td>155.0</td>\n",
       "      <td>651.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1.0</td>\n",
       "      <td>password</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2471056</th>\n",
       "      <td>1556357235</td>\n",
       "      <td>192.168.1.39</td>\n",
       "      <td>51289.0</td>\n",
       "      <td>192.168.1.1</td>\n",
       "      <td>53.0</td>\n",
       "      <td>udp</td>\n",
       "      <td>dns</td>\n",
       "      <td>0.004012</td>\n",
       "      <td>74.0</td>\n",
       "      <td>90.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1.0</td>\n",
       "      <td>xss</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10714842</th>\n",
       "      <td>1556311785</td>\n",
       "      <td>192.168.1.32</td>\n",
       "      <td>50610.0</td>\n",
       "      <td>192.168.1.195</td>\n",
       "      <td>80.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>http</td>\n",
       "      <td>0.369658</td>\n",
       "      <td>263.0</td>\n",
       "      <td>467.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1.0</td>\n",
       "      <td>password</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16581481</th>\n",
       "      <td>1556234656</td>\n",
       "      <td>192.168.1.30</td>\n",
       "      <td>55230.0</td>\n",
       "      <td>192.168.1.190</td>\n",
       "      <td>80.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>0.000411</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1.0</td>\n",
       "      <td>ddos</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13464835</th>\n",
       "      <td>1556076381</td>\n",
       "      <td>192.168.1.190</td>\n",
       "      <td>5961.0</td>\n",
       "      <td>192.168.1.32</td>\n",
       "      <td>57548.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1.0</td>\n",
       "      <td>scanning</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19689745</th>\n",
       "      <td>1556078097</td>\n",
       "      <td>192.168.1.31</td>\n",
       "      <td>51129.0</td>\n",
       "      <td>192.168.1.194</td>\n",
       "      <td>5999.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1.0</td>\n",
       "      <td>scanning</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>2197863 rows × 45 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                  ts         src_ip  src_port         dst_ip  dst_port proto  \\\n",
       "11296090  1556027596   192.168.1.32   64386.0  192.168.35.70      80.0   tcp   \n",
       "4548155   1556226499   192.168.1.31   54888.0  192.168.1.190      80.0   tcp   \n",
       "21842540  1556221235   192.168.1.31   55574.0  192.168.1.152      80.0   tcp   \n",
       "17338199  1556367296   192.168.1.35   44801.0    192.168.1.1      53.0   udp   \n",
       "10681504  1556310888   192.168.1.32   43152.0  192.168.1.190      80.0   tcp   \n",
       "...              ...            ...       ...            ...       ...   ...   \n",
       "2471056   1556357235   192.168.1.39   51289.0    192.168.1.1      53.0   udp   \n",
       "10714842  1556311785   192.168.1.32   50610.0  192.168.1.195      80.0   tcp   \n",
       "16581481  1556234656   192.168.1.30   55230.0  192.168.1.190      80.0   tcp   \n",
       "13464835  1556076381  192.168.1.190    5961.0   192.168.1.32   57548.0   tcp   \n",
       "19689745  1556078097   192.168.1.31   51129.0  192.168.1.194    5999.0   tcp   \n",
       "\n",
       "         service   duration  src_bytes  dst_bytes  ... http_response_body_len  \\\n",
       "11296090       -   0.000000        0.0        0.0  ...                    0.0   \n",
       "4548155        -   0.000011        0.0        0.0  ...                    0.0   \n",
       "21842540       -  41.465948        0.0        0.0  ...                    0.0   \n",
       "17338199     dns   0.030778       80.0      112.0  ...                    0.0   \n",
       "10681504    http   0.002832      155.0      651.0  ...                    0.0   \n",
       "...          ...        ...        ...        ...  ...                    ...   \n",
       "2471056      dns   0.004012       74.0       90.0  ...                    0.0   \n",
       "10714842    http   0.369658      263.0      467.0  ...                    0.0   \n",
       "16581481       -   0.000411        0.0        0.0  ...                    0.0   \n",
       "13464835       -   0.000000        0.0        0.0  ...                    0.0   \n",
       "19689745       -   0.000000        0.0        0.0  ...                    0.0   \n",
       "\n",
       "          http_status_code  http_user_agent  http_orig_mime_types  \\\n",
       "11296090               0.0                -                     -   \n",
       "4548155                0.0                -                     -   \n",
       "21842540               0.0                -                     -   \n",
       "17338199               0.0                -                     -   \n",
       "10681504               0.0                -                     -   \n",
       "...                    ...              ...                   ...   \n",
       "2471056                0.0                -                     -   \n",
       "10714842               0.0                -                     -   \n",
       "16581481               0.0                -                     -   \n",
       "13464835               0.0                -                     -   \n",
       "19689745               0.0                -                     -   \n",
       "\n",
       "          http_resp_mime_types  weird_name weird_addl  weird_notice  label  \\\n",
       "11296090                     -           -          -             -    1.0   \n",
       "4548155                      -           -          -             -    1.0   \n",
       "21842540                     -           -          -             -    1.0   \n",
       "17338199                     -           -          -             -    1.0   \n",
       "10681504                     -           -          -             -    1.0   \n",
       "...                        ...         ...        ...           ...    ...   \n",
       "2471056                      -           -          -             -    1.0   \n",
       "10714842                     -           -          -             -    1.0   \n",
       "16581481                     -           -          -             -    1.0   \n",
       "13464835                     -           -          -             -    1.0   \n",
       "19689745                     -           -          -             -    1.0   \n",
       "\n",
       "              type  \n",
       "11296090  scanning  \n",
       "4548155       ddos  \n",
       "21842540      ddos  \n",
       "17338199       xss  \n",
       "10681504  password  \n",
       "...            ...  \n",
       "2471056        xss  \n",
       "10714842  password  \n",
       "16581481      ddos  \n",
       "13464835  scanning  \n",
       "19689745  scanning  \n",
       "\n",
       "[2197863 rows x 45 columns]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "data['src_ip'] = data.src_ip.apply(lambda x: socket.inet_ntoa(struct.pack('>I', random.randint(0xac100001, 0xac1f0001))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "data['src_ip'] = data.src_ip.apply(str)\n",
    "data['src_port'] = data.src_port.apply(str)\n",
    "data['dst_ip'] = data.dst_ip.apply(str)\n",
    "data['dst_port'] = data.dst_port.apply(str)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "data['src_ip'] = data['src_ip'] + ':' + data['src_port']\n",
    "data['dst_ip'] = data['dst_ip'] + ':' + data['dst_port']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "scanning      713644\n",
       "ddos          617121\n",
       "dos           336744\n",
       "xss           211404\n",
       "password      136342\n",
       "normal         78957\n",
       "backdoor       50779\n",
       "injection      45449\n",
       "ransomware      7319\n",
       "mitm             104\n",
       "Name: type, dtype: int64"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.type.value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(['-', '1', '2', '7', '3', '5'], dtype=object)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data['http_trans_depth'].unique()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "data.drop(columns=['ts','src_port','dst_port','http_uri','weird_name','weird_addl','weird_notice','dns_query','ssl_subject','ssl_issuer','http_user_agent','type'],inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "#le = LabelEncoder()\n",
    "#le.fit(data.label.values)\n",
    "#data['label'] = le.transform(data['label'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "data['label'] = data.label.apply(int)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "label = data.label"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "data.drop(columns=['label'],inplace = True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "scaler = StandardScaler()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "data =  pd.concat([data, label], axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "     data, label, test_size=0.3, random_state=123,stratify= label)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>src_ip</th>\n",
       "      <th>dst_ip</th>\n",
       "      <th>proto</th>\n",
       "      <th>service</th>\n",
       "      <th>duration</th>\n",
       "      <th>src_bytes</th>\n",
       "      <th>dst_bytes</th>\n",
       "      <th>conn_state</th>\n",
       "      <th>missed_bytes</th>\n",
       "      <th>src_pkts</th>\n",
       "      <th>...</th>\n",
       "      <th>ssl_established</th>\n",
       "      <th>http_trans_depth</th>\n",
       "      <th>http_method</th>\n",
       "      <th>http_version</th>\n",
       "      <th>http_request_body_len</th>\n",
       "      <th>http_response_body_len</th>\n",
       "      <th>http_status_code</th>\n",
       "      <th>http_orig_mime_types</th>\n",
       "      <th>http_resp_mime_types</th>\n",
       "      <th>label</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>12518989</th>\n",
       "      <td>172.22.130.149:5906.0</td>\n",
       "      <td>192.168.1.194:5906.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>0.000020</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>REJ</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>...</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16767139</th>\n",
       "      <td>172.29.77.4:55306.0</td>\n",
       "      <td>192.168.1.1:53.0</td>\n",
       "      <td>udp</td>\n",
       "      <td>dns</td>\n",
       "      <td>0.002121</td>\n",
       "      <td>43.0</td>\n",
       "      <td>43.0</td>\n",
       "      <td>SF</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>...</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15443196</th>\n",
       "      <td>172.18.90.201:3.0</td>\n",
       "      <td>192.168.1.194:3.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>0.000024</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>REJ</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>...</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8315251</th>\n",
       "      <td>172.16.104.4:38932.0</td>\n",
       "      <td>18.194.169.124:80.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>http</td>\n",
       "      <td>1.179152</td>\n",
       "      <td>2806.0</td>\n",
       "      <td>1456.0</td>\n",
       "      <td>SF</td>\n",
       "      <td>0.0</td>\n",
       "      <td>7.0</td>\n",
       "      <td>...</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5080887</th>\n",
       "      <td>172.30.105.50:40210.0</td>\n",
       "      <td>192.168.1.190:80.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>0.000385</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>S1</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>...</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16954071</th>\n",
       "      <td>172.21.86.98:42124.0</td>\n",
       "      <td>192.168.1.184:80.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>http</td>\n",
       "      <td>0.012523</td>\n",
       "      <td>196.0</td>\n",
       "      <td>107.0</td>\n",
       "      <td>SF</td>\n",
       "      <td>0.0</td>\n",
       "      <td>6.0</td>\n",
       "      <td>...</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5608250</th>\n",
       "      <td>172.16.105.142:48974.0</td>\n",
       "      <td>192.168.1.194:80.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>6.098154</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>S1</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>...</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16899259</th>\n",
       "      <td>172.22.79.223:58146.0</td>\n",
       "      <td>192.168.1.184:443.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>60.515091</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>S3</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>...</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16292605</th>\n",
       "      <td>172.28.55.230:52940.0</td>\n",
       "      <td>192.168.1.184:443.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>64.609299</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>S3</td>\n",
       "      <td>0.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>...</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16765599</th>\n",
       "      <td>172.21.33.221:36902.0</td>\n",
       "      <td>192.168.1.184:443.0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>-</td>\n",
       "      <td>60.194978</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>S3</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>...</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-</td>\n",
       "      <td>-</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1538504 rows × 33 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                          src_ip                dst_ip proto service  \\\n",
       "12518989   172.22.130.149:5906.0  192.168.1.194:5906.0   tcp       -   \n",
       "16767139     172.29.77.4:55306.0      192.168.1.1:53.0   udp     dns   \n",
       "15443196       172.18.90.201:3.0     192.168.1.194:3.0   tcp       -   \n",
       "8315251     172.16.104.4:38932.0   18.194.169.124:80.0   tcp    http   \n",
       "5080887    172.30.105.50:40210.0    192.168.1.190:80.0   tcp       -   \n",
       "...                          ...                   ...   ...     ...   \n",
       "16954071    172.21.86.98:42124.0    192.168.1.184:80.0   tcp    http   \n",
       "5608250   172.16.105.142:48974.0    192.168.1.194:80.0   tcp       -   \n",
       "16899259   172.22.79.223:58146.0   192.168.1.184:443.0   tcp       -   \n",
       "16292605   172.28.55.230:52940.0   192.168.1.184:443.0   tcp       -   \n",
       "16765599   172.21.33.221:36902.0   192.168.1.184:443.0   tcp       -   \n",
       "\n",
       "           duration  src_bytes  dst_bytes conn_state  missed_bytes  src_pkts  \\\n",
       "12518989   0.000020        0.0        0.0        REJ           0.0       1.0   \n",
       "16767139   0.002121       43.0       43.0         SF           0.0       1.0   \n",
       "15443196   0.000024        0.0        0.0        REJ           0.0       1.0   \n",
       "8315251    1.179152     2806.0     1456.0         SF           0.0       7.0   \n",
       "5080887    0.000385        0.0        0.0         S1           0.0       2.0   \n",
       "...             ...        ...        ...        ...           ...       ...   \n",
       "16954071   0.012523      196.0      107.0         SF           0.0       6.0   \n",
       "5608250    6.098154        0.0        0.0         S1           0.0       2.0   \n",
       "16899259  60.515091        0.0        0.0         S3           0.0       2.0   \n",
       "16292605  64.609299        0.0        0.0         S3           0.0       3.0   \n",
       "16765599  60.194978        0.0        0.0         S3           0.0       2.0   \n",
       "\n",
       "          ...  ssl_established  http_trans_depth  http_method  http_version  \\\n",
       "12518989  ...                -                 -            -             -   \n",
       "16767139  ...                -                 -            -             -   \n",
       "15443196  ...                -                 -            -             -   \n",
       "8315251   ...                -                 -            -             -   \n",
       "5080887   ...                -                 -            -             -   \n",
       "...       ...              ...               ...          ...           ...   \n",
       "16954071  ...                -                 -            -             -   \n",
       "5608250   ...                -                 -            -             -   \n",
       "16899259  ...                -                 -            -             -   \n",
       "16292605  ...                -                 -            -             -   \n",
       "16765599  ...                -                 -            -             -   \n",
       "\n",
       "          http_request_body_len  http_response_body_len http_status_code  \\\n",
       "12518989                    0.0                     0.0              0.0   \n",
       "16767139                    0.0                     0.0              0.0   \n",
       "15443196                    0.0                     0.0              0.0   \n",
       "8315251                     0.0                     0.0              0.0   \n",
       "5080887                     0.0                     0.0              0.0   \n",
       "...                         ...                     ...              ...   \n",
       "16954071                    0.0                     0.0              0.0   \n",
       "5608250                     0.0                     0.0              0.0   \n",
       "16899259                    0.0                     0.0              0.0   \n",
       "16292605                    0.0                     0.0              0.0   \n",
       "16765599                    0.0                     0.0              0.0   \n",
       "\n",
       "         http_orig_mime_types http_resp_mime_types label  \n",
       "12518989                    -                    -     1  \n",
       "16767139                    -                    -     1  \n",
       "15443196                    -                    -     1  \n",
       "8315251                     -                    -     1  \n",
       "5080887                     -                    -     1  \n",
       "...                       ...                  ...   ...  \n",
       "16954071                    -                    -     1  \n",
       "5608250                     -                    -     1  \n",
       "16899259                    -                    -     1  \n",
       "16292605                    -                    -     1  \n",
       "16765599                    -                    -     1  \n",
       "\n",
       "[1538504 rows x 33 columns]"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "encoder = ce.TargetEncoder(cols=['proto','service','conn_state','dns_qclass','dns_qtype','dns_rcode','dns_AA','dns_RD','dns_RA','dns_rejected','ssl_version','ssl_cipher','ssl_resumed','ssl_established','http_method','http_version','http_status_code','http_orig_mime_types','http_resp_mime_types','http_trans_depth'])\n",
    "encoder.fit(X_train, y_train)\n",
    "X_train = encoder.transform(X_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "cols_to_norm = list(set(list(X_train.iloc[:, 2:].columns ))  - set(list(['label'])) )\n",
    "X_train[cols_to_norm] = scaler.fit_transform(X_train[cols_to_norm])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train['h'] = X_train[ cols_to_norm ].values.tolist()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>src_ip</th>\n",
       "      <th>dst_ip</th>\n",
       "      <th>proto</th>\n",
       "      <th>service</th>\n",
       "      <th>duration</th>\n",
       "      <th>src_bytes</th>\n",
       "      <th>dst_bytes</th>\n",
       "      <th>conn_state</th>\n",
       "      <th>missed_bytes</th>\n",
       "      <th>src_pkts</th>\n",
       "      <th>...</th>\n",
       "      <th>http_trans_depth</th>\n",
       "      <th>http_method</th>\n",
       "      <th>http_version</th>\n",
       "      <th>http_request_body_len</th>\n",
       "      <th>http_response_body_len</th>\n",
       "      <th>http_status_code</th>\n",
       "      <th>http_orig_mime_types</th>\n",
       "      <th>http_resp_mime_types</th>\n",
       "      <th>label</th>\n",
       "      <th>h</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>12518989</th>\n",
       "      <td>172.22.130.149:5906.0</td>\n",
       "      <td>192.168.1.194:5906.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.196550</td>\n",
       "      <td>-0.091245</td>\n",
       "      <td>-0.027508</td>\n",
       "      <td>-0.023848</td>\n",
       "      <td>0.500885</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.028383</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "      <td>[0.020306524458986664, -0.012225578106630998, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16767139</th>\n",
       "      <td>172.29.77.4:55306.0</td>\n",
       "      <td>192.168.1.1:53.0</td>\n",
       "      <td>-3.18382</td>\n",
       "      <td>-3.544340</td>\n",
       "      <td>-0.091223</td>\n",
       "      <td>-0.027507</td>\n",
       "      <td>-0.023847</td>\n",
       "      <td>-0.012306</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.028383</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "      <td>[-0.3270084691238662, -0.011169861427262529, -...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15443196</th>\n",
       "      <td>172.18.90.201:3.0</td>\n",
       "      <td>192.168.1.194:3.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.196550</td>\n",
       "      <td>-0.091245</td>\n",
       "      <td>-0.027508</td>\n",
       "      <td>-0.023848</td>\n",
       "      <td>0.500885</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.028383</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "      <td>[0.020306524458986664, -0.012225578106630998, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8315251</th>\n",
       "      <td>172.16.104.4:38932.0</td>\n",
       "      <td>18.194.169.124:80.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.595997</td>\n",
       "      <td>-0.079040</td>\n",
       "      <td>-0.027426</td>\n",
       "      <td>-0.023804</td>\n",
       "      <td>-0.012306</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>0.026424</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "      <td>[0.020306524458986664, 0.09464019414686126, 0....</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5080887</th>\n",
       "      <td>172.30.105.50:40210.0</td>\n",
       "      <td>192.168.1.190:80.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.196550</td>\n",
       "      <td>-0.091241</td>\n",
       "      <td>-0.027508</td>\n",
       "      <td>-0.023848</td>\n",
       "      <td>0.459808</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.019249</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "      <td>[0.020306524458986664, -0.009773590980355842, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16954071</th>\n",
       "      <td>172.21.86.98:42124.0</td>\n",
       "      <td>192.168.1.184:80.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.595997</td>\n",
       "      <td>-0.091115</td>\n",
       "      <td>-0.027502</td>\n",
       "      <td>-0.023845</td>\n",
       "      <td>-0.012306</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>0.017290</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "      <td>[0.020306524458986664, 0.003984781228188094, 0...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5608250</th>\n",
       "      <td>172.16.105.142:48974.0</td>\n",
       "      <td>192.168.1.194:80.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.196550</td>\n",
       "      <td>-0.028127</td>\n",
       "      <td>-0.027508</td>\n",
       "      <td>-0.023848</td>\n",
       "      <td>0.459808</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.019249</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "      <td>[0.020306524458986664, -0.010046033994386415, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16899259</th>\n",
       "      <td>172.22.79.223:58146.0</td>\n",
       "      <td>192.168.1.184:443.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.196550</td>\n",
       "      <td>0.535105</td>\n",
       "      <td>-0.027508</td>\n",
       "      <td>-0.023848</td>\n",
       "      <td>0.498219</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.019249</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "      <td>[0.020306524458986664, -0.009773590980355842, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16292605</th>\n",
       "      <td>172.28.55.230:52940.0</td>\n",
       "      <td>192.168.1.184:443.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.196550</td>\n",
       "      <td>0.577481</td>\n",
       "      <td>-0.027508</td>\n",
       "      <td>-0.023848</td>\n",
       "      <td>0.498219</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.010114</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "      <td>[0.020306524458986664, -0.008002711389157117, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16765599</th>\n",
       "      <td>172.21.33.221:36902.0</td>\n",
       "      <td>192.168.1.184:443.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.196550</td>\n",
       "      <td>0.531792</td>\n",
       "      <td>-0.027508</td>\n",
       "      <td>-0.023848</td>\n",
       "      <td>0.498219</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.019249</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "      <td>[0.020306524458986664, -0.009773590980355842, ...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1538504 rows × 34 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                          src_ip                dst_ip    proto   service  \\\n",
       "12518989   172.22.130.149:5906.0  192.168.1.194:5906.0  0.27687  0.196550   \n",
       "16767139     172.29.77.4:55306.0      192.168.1.1:53.0 -3.18382 -3.544340   \n",
       "15443196       172.18.90.201:3.0     192.168.1.194:3.0  0.27687  0.196550   \n",
       "8315251     172.16.104.4:38932.0   18.194.169.124:80.0  0.27687  0.595997   \n",
       "5080887    172.30.105.50:40210.0    192.168.1.190:80.0  0.27687  0.196550   \n",
       "...                          ...                   ...      ...       ...   \n",
       "16954071    172.21.86.98:42124.0    192.168.1.184:80.0  0.27687  0.595997   \n",
       "5608250   172.16.105.142:48974.0    192.168.1.194:80.0  0.27687  0.196550   \n",
       "16899259   172.22.79.223:58146.0   192.168.1.184:443.0  0.27687  0.196550   \n",
       "16292605   172.28.55.230:52940.0   192.168.1.184:443.0  0.27687  0.196550   \n",
       "16765599   172.21.33.221:36902.0   192.168.1.184:443.0  0.27687  0.196550   \n",
       "\n",
       "          duration  src_bytes  dst_bytes  conn_state  missed_bytes  src_pkts  \\\n",
       "12518989 -0.091245  -0.027508  -0.023848    0.500885     -0.007537 -0.028383   \n",
       "16767139 -0.091223  -0.027507  -0.023847   -0.012306     -0.007537 -0.028383   \n",
       "15443196 -0.091245  -0.027508  -0.023848    0.500885     -0.007537 -0.028383   \n",
       "8315251  -0.079040  -0.027426  -0.023804   -0.012306     -0.007537  0.026424   \n",
       "5080887  -0.091241  -0.027508  -0.023848    0.459808     -0.007537 -0.019249   \n",
       "...            ...        ...        ...         ...           ...       ...   \n",
       "16954071 -0.091115  -0.027502  -0.023845   -0.012306     -0.007537  0.017290   \n",
       "5608250  -0.028127  -0.027508  -0.023848    0.459808     -0.007537 -0.019249   \n",
       "16899259  0.535105  -0.027508  -0.023848    0.498219     -0.007537 -0.019249   \n",
       "16292605  0.577481  -0.027508  -0.023848    0.498219     -0.007537 -0.010114   \n",
       "16765599  0.531792  -0.027508  -0.023848    0.498219     -0.007537 -0.019249   \n",
       "\n",
       "          ...  http_trans_depth  http_method  http_version  \\\n",
       "12518989  ...         -0.032746    -0.030454     -0.032517   \n",
       "16767139  ...         -0.032746    -0.030454     -0.032517   \n",
       "15443196  ...         -0.032746    -0.030454     -0.032517   \n",
       "8315251   ...         -0.032746    -0.030454     -0.032517   \n",
       "5080887   ...         -0.032746    -0.030454     -0.032517   \n",
       "...       ...               ...          ...           ...   \n",
       "16954071  ...         -0.032746    -0.030454     -0.032517   \n",
       "5608250   ...         -0.032746    -0.030454     -0.032517   \n",
       "16899259  ...         -0.032746    -0.030454     -0.032517   \n",
       "16292605  ...         -0.032746    -0.030454     -0.032517   \n",
       "16765599  ...         -0.032746    -0.030454     -0.032517   \n",
       "\n",
       "          http_request_body_len  http_response_body_len  http_status_code  \\\n",
       "12518989              -0.001991               -0.003418         -0.016846   \n",
       "16767139              -0.001991               -0.003418         -0.016846   \n",
       "15443196              -0.001991               -0.003418         -0.016846   \n",
       "8315251               -0.001991               -0.003418         -0.016846   \n",
       "5080887               -0.001991               -0.003418         -0.016846   \n",
       "...                         ...                     ...               ...   \n",
       "16954071              -0.001991               -0.003418         -0.016846   \n",
       "5608250               -0.001991               -0.003418         -0.016846   \n",
       "16899259              -0.001991               -0.003418         -0.016846   \n",
       "16292605              -0.001991               -0.003418         -0.016846   \n",
       "16765599              -0.001991               -0.003418         -0.016846   \n",
       "\n",
       "          http_orig_mime_types  http_resp_mime_types  label  \\\n",
       "12518989             -0.007433             -0.001272      1   \n",
       "16767139             -0.007433             -0.001272      1   \n",
       "15443196             -0.007433             -0.001272      1   \n",
       "8315251              -0.007433             -0.001272      1   \n",
       "5080887              -0.007433             -0.001272      1   \n",
       "...                        ...                   ...    ...   \n",
       "16954071             -0.007433             -0.001272      1   \n",
       "5608250              -0.007433             -0.001272      1   \n",
       "16899259             -0.007433             -0.001272      1   \n",
       "16292605             -0.007433             -0.001272      1   \n",
       "16765599             -0.007433             -0.001272      1   \n",
       "\n",
       "                                                          h  \n",
       "12518989  [0.020306524458986664, -0.012225578106630998, ...  \n",
       "16767139  [-0.3270084691238662, -0.011169861427262529, -...  \n",
       "15443196  [0.020306524458986664, -0.012225578106630998, ...  \n",
       "8315251   [0.020306524458986664, 0.09464019414686126, 0....  \n",
       "5080887   [0.020306524458986664, -0.009773590980355842, ...  \n",
       "...                                                     ...  \n",
       "16954071  [0.020306524458986664, 0.003984781228188094, 0...  \n",
       "5608250   [0.020306524458986664, -0.010046033994386415, ...  \n",
       "16899259  [0.020306524458986664, -0.009773590980355842, ...  \n",
       "16292605  [0.020306524458986664, -0.008002711389157117, ...  \n",
       "16765599  [0.020306524458986664, -0.009773590980355842, ...  \n",
       "\n",
       "[1538504 rows x 34 columns]"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "G = nx.from_pandas_edgelist(X_train, \"src_ip\", \"dst_ip\", ['h','label'],create_using=nx.MultiGraph())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "G = G.to_directed()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "G = from_networkx(G,edge_attrs=['h','label'] )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "G.ndata['h'] = th.ones(G.num_nodes(), G.edata['h'].shape[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "G.ndata['h'] = th.reshape(G.ndata['h'], (G.ndata['h'].shape[0], 1,G.ndata['h'].shape[1]))\n",
    "G.edata['h'] = th.reshape(G.edata['h'], (G.edata['h'].shape[0], 1,G.edata['h'].shape[1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "G.edata['train_mask'] = th.ones(len(G.edata['h']), dtype=th.bool)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Model(nn.Module):\n",
    "    def __init__(self, ndim_in, ndim_out, edim, activation, dropout):\n",
    "        super().__init__()\n",
    "        self.gnn = SAGE(ndim_in, ndim_out, edim, activation, dropout)\n",
    "        self.pred = MLPPredictor(ndim_out, 2)\n",
    "    def forward(self, g, nfeats, efeats):\n",
    "        h = self.gnn(g, nfeats, efeats)\n",
    "        return self.pred(g, h)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "class SAGELayer(nn.Module):\n",
    "    def __init__(self, ndim_in, edims, ndim_out, activation):\n",
    "        super(SAGELayer, self).__init__()\n",
    "        ### force to outut fix dimensions\n",
    "        self.W_msg = nn.Linear(ndim_in + edims, ndim_out)\n",
    "        ### apply weight\n",
    "        self.W_apply = nn.Linear(ndim_in + ndim_out, ndim_out)\n",
    "        self.activation = activation\n",
    "\n",
    "    def message_func(self, edges):\n",
    "        return {'m': self.W_msg(th.cat([edges.src['h'], edges.data['h']], 2))}\n",
    "\n",
    "    def forward(self, g_dgl, nfeats, efeats):\n",
    "        with g_dgl.local_scope():\n",
    "            g = g_dgl\n",
    "            g.ndata['h'] = nfeats\n",
    "            g.edata['h'] = efeats\n",
    "            # Eq4\n",
    "            g.update_all(self.message_func, fn.mean('m', 'h_neigh'))\n",
    "            # Eq5          \n",
    "            g.ndata['h'] = F.relu(self.W_apply(th.cat([g.ndata['h'], g.ndata['h_neigh']], 2)))\n",
    "            return g.ndata['h']\n",
    "\n",
    "\n",
    "class SAGE(nn.Module):\n",
    "    def __init__(self, ndim_in, ndim_out, edim, activation, dropout):\n",
    "        super(SAGE, self).__init__()\n",
    "        self.layers = nn.ModuleList()\n",
    "        self.layers.append(SAGELayer(ndim_in, edim, 128, activation))\n",
    "        self.layers.append(SAGELayer(128, edim, ndim_out, activation))\n",
    "        self.dropout = nn.Dropout(p=dropout)\n",
    "\n",
    "    def forward(self, g, nfeats, efeats):\n",
    "        for i, layer in enumerate(self.layers):\n",
    "            if i != 0:\n",
    "                nfeats = self.dropout(nfeats)\n",
    "            nfeats = layer(g, nfeats, efeats)\n",
    "        return nfeats.sum(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "class MLPPredictor(nn.Module):\n",
    "    def __init__(self, in_features, out_classes):\n",
    "        super().__init__()\n",
    "        self.W = nn.Linear(in_features * 2, out_classes)\n",
    "\n",
    "    def apply_edges(self, edges):\n",
    "        h_u = edges.src['h']\n",
    "        h_v = edges.dst['h']\n",
    "        score = self.W(th.cat([h_u, h_v], 1))\n",
    "        return {'score': score}\n",
    "\n",
    "    def forward(self, graph, h):\n",
    "        with graph.local_scope():\n",
    "            graph.ndata['h'] = h\n",
    "            graph.apply_edges(self.apply_edges)\n",
    "            return graph.edata['score']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "device(type='cuda', index=0)"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "G = G.to('cuda:0')\n",
    "G.device"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "device(type='cuda', index=0)"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "G.ndata['h'].device\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "device(type='cuda', index=0)"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "G.edata['h'].device\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.utils import class_weight\n",
    "class_weights = class_weight.compute_class_weight('balanced',\n",
    "                                                 np.unique(G.edata['label'].cpu().numpy()),\n",
    "                                                 G.edata['label'].cpu().numpy())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "#class_weights = [10,1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "class_weights = th.FloatTensor(class_weights).cuda()\n",
    "criterion = nn.CrossEntropyLoss(weight = class_weights)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "def compute_accuracy(pred, labels):\n",
    "    return (pred.argmax(1) == labels).float().mean().item()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch: 100  Training acc: 0.9724498391151428\n",
      "Epoch: 200  Training acc: 0.9738720059394836\n",
      "Epoch: 300  Training acc: 0.9744514226913452\n",
      "Epoch: 400  Training acc: 0.9753386974334717\n",
      "Epoch: 500  Training acc: 0.9754420518875122\n",
      "Epoch: 600  Training acc: 0.9762665033340454\n",
      "Epoch: 700  Training acc: 0.9762275218963623\n",
      "Epoch: 800  Training acc: 0.9761020541191101\n",
      "Epoch: 900  Training acc: 0.9765200018882751\n",
      "Epoch: 1000  Training acc: 0.976667582988739\n",
      "Epoch: 1100  Training acc: 0.9766178131103516\n",
      "Epoch: 1200  Training acc: 0.97658371925354\n",
      "Epoch: 1300  Training acc: 0.9766139388084412\n",
      "Epoch: 1400  Training acc: 0.9765151739120483\n",
      "Epoch: 1500  Training acc: 0.9767189025878906\n",
      "Epoch: 1600  Training acc: 0.9763389825820923\n",
      "Epoch: 1700  Training acc: 0.976122260093689\n",
      "Epoch: 1800  Training acc: 0.9771137833595276\n",
      "Epoch: 1900  Training acc: 0.9771524667739868\n",
      "Epoch: 2000  Training acc: 0.9764358401298523\n",
      "Epoch: 2100  Training acc: 0.9778047204017639\n",
      "Epoch: 2200  Training acc: 0.9780842065811157\n",
      "Epoch: 2300  Training acc: 0.978377640247345\n",
      "Epoch: 2400  Training acc: 0.978896975517273\n",
      "Epoch: 2500  Training acc: 0.9781118035316467\n",
      "Epoch: 2600  Training acc: 0.9784524440765381\n",
      "Epoch: 2700  Training acc: 0.978788435459137\n",
      "Epoch: 2800  Training acc: 0.9786422252655029\n",
      "Epoch: 2900  Training acc: 0.978537917137146\n",
      "Epoch: 3000  Training acc: 0.9784228205680847\n",
      "Epoch: 3100  Training acc: 0.9787315726280212\n",
      "Epoch: 3200  Training acc: 0.9788993000984192\n",
      "Epoch: 3300  Training acc: 0.9791475534439087\n",
      "Epoch: 3400  Training acc: 0.9788011312484741\n"
     ]
    }
   ],
   "source": [
    "node_features = G.ndata['h']\n",
    "edge_features = G.edata['h']\n",
    "\n",
    "edge_label = G.edata['label']\n",
    "train_mask = G.edata['train_mask']\n",
    "\n",
    "model = Model(G.ndata['h'].shape[2], 128, G.ndata['h'].shape[2], F.relu, 0.2).cuda()\n",
    "opt = th.optim.Adam(model.parameters())\n",
    "\n",
    "\n",
    "for epoch in range(1,3500):\n",
    "    pred = model(G, node_features,edge_features).cuda()\n",
    "    loss = criterion(pred[train_mask] ,edge_label[train_mask])\n",
    "    opt.zero_grad()\n",
    "    loss.backward()\n",
    "    opt.step()\n",
    "    if epoch % 100 == 0:\n",
    "        print('Epoch:', epoch ,' Training acc:', compute_accuracy(pred[train_mask], edge_label[train_mask]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_test = encoder.transform(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_test[cols_to_norm] = scaler.transform(X_test[cols_to_norm])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>src_ip</th>\n",
       "      <th>dst_ip</th>\n",
       "      <th>proto</th>\n",
       "      <th>service</th>\n",
       "      <th>duration</th>\n",
       "      <th>src_bytes</th>\n",
       "      <th>dst_bytes</th>\n",
       "      <th>conn_state</th>\n",
       "      <th>missed_bytes</th>\n",
       "      <th>src_pkts</th>\n",
       "      <th>...</th>\n",
       "      <th>ssl_established</th>\n",
       "      <th>http_trans_depth</th>\n",
       "      <th>http_method</th>\n",
       "      <th>http_version</th>\n",
       "      <th>http_request_body_len</th>\n",
       "      <th>http_response_body_len</th>\n",
       "      <th>http_status_code</th>\n",
       "      <th>http_orig_mime_types</th>\n",
       "      <th>http_resp_mime_types</th>\n",
       "      <th>label</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>16917728</th>\n",
       "      <td>172.25.194.104:52364.0</td>\n",
       "      <td>192.168.1.190:80.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.196550</td>\n",
       "      <td>-0.091242</td>\n",
       "      <td>-0.027508</td>\n",
       "      <td>-0.023848</td>\n",
       "      <td>0.459808</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.019249</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.002536</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5551382</th>\n",
       "      <td>172.25.235.51:44936.0</td>\n",
       "      <td>192.168.1.1:53.0</td>\n",
       "      <td>-3.18382</td>\n",
       "      <td>-3.544340</td>\n",
       "      <td>-0.091201</td>\n",
       "      <td>-0.027507</td>\n",
       "      <td>-0.023847</td>\n",
       "      <td>-0.012306</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.028383</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.002536</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>568557</th>\n",
       "      <td>172.29.79.142:376.0</td>\n",
       "      <td>192.168.1.193:376.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.196550</td>\n",
       "      <td>-0.091245</td>\n",
       "      <td>-0.027508</td>\n",
       "      <td>-0.023848</td>\n",
       "      <td>0.500885</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.028383</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.002536</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17657520</th>\n",
       "      <td>172.30.242.165:49159.0</td>\n",
       "      <td>192.168.1.37:8001.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.196550</td>\n",
       "      <td>-0.091245</td>\n",
       "      <td>-0.027508</td>\n",
       "      <td>-0.023848</td>\n",
       "      <td>-4.705624</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.028383</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.002536</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7559197</th>\n",
       "      <td>172.24.62.198:60578.0</td>\n",
       "      <td>192.168.1.190:80.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.595997</td>\n",
       "      <td>-0.091226</td>\n",
       "      <td>-0.027503</td>\n",
       "      <td>-0.023762</td>\n",
       "      <td>-0.012306</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>0.008155</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.002536</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17237283</th>\n",
       "      <td>172.18.136.0:59267.0</td>\n",
       "      <td>192.168.1.1:53.0</td>\n",
       "      <td>-3.18382</td>\n",
       "      <td>-3.544340</td>\n",
       "      <td>-0.045602</td>\n",
       "      <td>-0.027504</td>\n",
       "      <td>-0.023843</td>\n",
       "      <td>-0.012306</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.000980</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.002536</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15809665</th>\n",
       "      <td>172.17.19.25:38712.0</td>\n",
       "      <td>192.168.1.190:80.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.595997</td>\n",
       "      <td>-0.091219</td>\n",
       "      <td>-0.027503</td>\n",
       "      <td>-0.023758</td>\n",
       "      <td>-0.012306</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>0.008155</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.002536</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3430755</th>\n",
       "      <td>172.23.134.183:20102.0</td>\n",
       "      <td>192.168.1.152:14716.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.196550</td>\n",
       "      <td>-0.091181</td>\n",
       "      <td>-0.027508</td>\n",
       "      <td>-0.023848</td>\n",
       "      <td>0.500885</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.028383</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.002536</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12263615</th>\n",
       "      <td>172.25.130.150:5433.0</td>\n",
       "      <td>192.168.1.190:5433.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.196550</td>\n",
       "      <td>-0.091244</td>\n",
       "      <td>-0.027508</td>\n",
       "      <td>-0.023848</td>\n",
       "      <td>0.500885</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.028383</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.002536</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7313059</th>\n",
       "      <td>172.30.243.106:51526.0</td>\n",
       "      <td>192.168.1.33:8080.0</td>\n",
       "      <td>0.27687</td>\n",
       "      <td>0.196550</td>\n",
       "      <td>-0.091137</td>\n",
       "      <td>-0.027508</td>\n",
       "      <td>-0.023848</td>\n",
       "      <td>0.500885</td>\n",
       "      <td>-0.007537</td>\n",
       "      <td>-0.028383</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.002536</td>\n",
       "      <td>-0.032746</td>\n",
       "      <td>-0.030454</td>\n",
       "      <td>-0.032517</td>\n",
       "      <td>-0.001991</td>\n",
       "      <td>-0.003418</td>\n",
       "      <td>-0.016846</td>\n",
       "      <td>-0.007433</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>659359 rows × 33 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                          src_ip                 dst_ip    proto   service  \\\n",
       "16917728  172.25.194.104:52364.0     192.168.1.190:80.0  0.27687  0.196550   \n",
       "5551382    172.25.235.51:44936.0       192.168.1.1:53.0 -3.18382 -3.544340   \n",
       "568557       172.29.79.142:376.0    192.168.1.193:376.0  0.27687  0.196550   \n",
       "17657520  172.30.242.165:49159.0    192.168.1.37:8001.0  0.27687  0.196550   \n",
       "7559197    172.24.62.198:60578.0     192.168.1.190:80.0  0.27687  0.595997   \n",
       "...                          ...                    ...      ...       ...   \n",
       "17237283    172.18.136.0:59267.0       192.168.1.1:53.0 -3.18382 -3.544340   \n",
       "15809665    172.17.19.25:38712.0     192.168.1.190:80.0  0.27687  0.595997   \n",
       "3430755   172.23.134.183:20102.0  192.168.1.152:14716.0  0.27687  0.196550   \n",
       "12263615   172.25.130.150:5433.0   192.168.1.190:5433.0  0.27687  0.196550   \n",
       "7313059   172.30.243.106:51526.0    192.168.1.33:8080.0  0.27687  0.196550   \n",
       "\n",
       "          duration  src_bytes  dst_bytes  conn_state  missed_bytes  src_pkts  \\\n",
       "16917728 -0.091242  -0.027508  -0.023848    0.459808     -0.007537 -0.019249   \n",
       "5551382  -0.091201  -0.027507  -0.023847   -0.012306     -0.007537 -0.028383   \n",
       "568557   -0.091245  -0.027508  -0.023848    0.500885     -0.007537 -0.028383   \n",
       "17657520 -0.091245  -0.027508  -0.023848   -4.705624     -0.007537 -0.028383   \n",
       "7559197  -0.091226  -0.027503  -0.023762   -0.012306     -0.007537  0.008155   \n",
       "...            ...        ...        ...         ...           ...       ...   \n",
       "17237283 -0.045602  -0.027504  -0.023843   -0.012306     -0.007537 -0.000980   \n",
       "15809665 -0.091219  -0.027503  -0.023758   -0.012306     -0.007537  0.008155   \n",
       "3430755  -0.091181  -0.027508  -0.023848    0.500885     -0.007537 -0.028383   \n",
       "12263615 -0.091244  -0.027508  -0.023848    0.500885     -0.007537 -0.028383   \n",
       "7313059  -0.091137  -0.027508  -0.023848    0.500885     -0.007537 -0.028383   \n",
       "\n",
       "          ...  ssl_established  http_trans_depth  http_method  http_version  \\\n",
       "16917728  ...        -0.002536         -0.032746    -0.030454     -0.032517   \n",
       "5551382   ...        -0.002536         -0.032746    -0.030454     -0.032517   \n",
       "568557    ...        -0.002536         -0.032746    -0.030454     -0.032517   \n",
       "17657520  ...        -0.002536         -0.032746    -0.030454     -0.032517   \n",
       "7559197   ...        -0.002536         -0.032746    -0.030454     -0.032517   \n",
       "...       ...              ...               ...          ...           ...   \n",
       "17237283  ...        -0.002536         -0.032746    -0.030454     -0.032517   \n",
       "15809665  ...        -0.002536         -0.032746    -0.030454     -0.032517   \n",
       "3430755   ...        -0.002536         -0.032746    -0.030454     -0.032517   \n",
       "12263615  ...        -0.002536         -0.032746    -0.030454     -0.032517   \n",
       "7313059   ...        -0.002536         -0.032746    -0.030454     -0.032517   \n",
       "\n",
       "          http_request_body_len  http_response_body_len  http_status_code  \\\n",
       "16917728              -0.001991               -0.003418         -0.016846   \n",
       "5551382               -0.001991               -0.003418         -0.016846   \n",
       "568557                -0.001991               -0.003418         -0.016846   \n",
       "17657520              -0.001991               -0.003418         -0.016846   \n",
       "7559197               -0.001991               -0.003418         -0.016846   \n",
       "...                         ...                     ...               ...   \n",
       "17237283              -0.001991               -0.003418         -0.016846   \n",
       "15809665              -0.001991               -0.003418         -0.016846   \n",
       "3430755               -0.001991               -0.003418         -0.016846   \n",
       "12263615              -0.001991               -0.003418         -0.016846   \n",
       "7313059               -0.001991               -0.003418         -0.016846   \n",
       "\n",
       "          http_orig_mime_types  http_resp_mime_types  label  \n",
       "16917728             -0.007433             -0.001272      1  \n",
       "5551382              -0.007433             -0.001272      1  \n",
       "568557               -0.007433             -0.001272      1  \n",
       "17657520             -0.007433             -0.001272      1  \n",
       "7559197              -0.007433             -0.001272      1  \n",
       "...                        ...                   ...    ...  \n",
       "17237283             -0.007433             -0.001272      1  \n",
       "15809665             -0.007433             -0.001272      1  \n",
       "3430755              -0.007433             -0.001272      1  \n",
       "12263615             -0.007433             -0.001272      1  \n",
       "7313059              -0.007433             -0.001272      1  \n",
       "\n",
       "[659359 rows x 33 columns]"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_test['h'] = X_test[ cols_to_norm ].values.tolist()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "G_test = nx.from_pandas_edgelist(X_test, \"src_ip\", \"dst_ip\", ['h','label'],create_using=nx.MultiGraph())\n",
    "G_test = G_test.to_directed()\n",
    "G_test = from_networkx(G_test,edge_attrs=['h','label'] )\n",
    "actual = G_test.edata.pop('label')\n",
    "G_test.ndata['feature'] = th.ones(G_test.num_nodes(),G.ndata['h'].shape[2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "G_test.ndata['feature'] = th.reshape(G_test.ndata['feature'], (G_test.ndata['feature'].shape[0], 1, G_test.ndata['feature'].shape[1]))\n",
    "G_test.edata['h'] = th.reshape(G_test.edata['h'], (G_test.edata['h'].shape[0], 1, G_test.edata['h'].shape[1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "G_test = G_test.to('cuda:0')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "import timeit\n",
    "start_time = timeit.default_timer()\n",
    "node_features_test = G_test.ndata['feature']\n",
    "edge_features_test = G_test.edata['h']\n",
    "test_pred = model(G_test, node_features_test, edge_features_test).cuda()\n",
    "elapsed = timeit.default_timer() - start_time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.09288323899818351 seconds\n"
     ]
    }
   ],
   "source": [
    "print(str(elapsed) + ' seconds')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_pred = test_pred.argmax(1)\n",
    "test_pred = th.Tensor.cpu(test_pred).detach().numpy()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [],
   "source": [
    "actual = [\"Normal\" if i == 0 else \"Attack\" for i in actual]\n",
    "test_pred = [\"Normal\" if i == 0 else \"Attack\" for i in test_pred]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import plot_confusion_matrix\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "\n",
    "def plot_confusion_matrix(cm,\n",
    "                          target_names,\n",
    "                          title='Confusion matrix',\n",
    "                          cmap=None,\n",
    "                          normalize=True):\n",
    "    \n",
    "    import matplotlib.pyplot as plt\n",
    "    import numpy as np\n",
    "    import itertools\n",
    "\n",
    "    accuracy = np.trace(cm) / float(np.sum(cm))\n",
    "    misclass = 1 - accuracy\n",
    "\n",
    "    if cmap is None:\n",
    "        cmap = plt.get_cmap('Blues')\n",
    "\n",
    "    plt.figure(figsize=(12, 12))\n",
    "    plt.imshow(cm, interpolation='nearest', cmap=cmap)\n",
    "    plt.title(title)\n",
    "    plt.colorbar()\n",
    "\n",
    "    if target_names is not None:\n",
    "        tick_marks = np.arange(len(target_names))\n",
    "        plt.xticks(tick_marks, target_names, rotation=45)\n",
    "        plt.yticks(tick_marks, target_names)\n",
    "\n",
    "    if normalize:\n",
    "        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n",
    "\n",
    "\n",
    "    thresh = cm.max() / 1.5 if normalize else cm.max() / 2\n",
    "    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n",
    "        if normalize:\n",
    "            plt.text(j, i, \"{:0.4f}\".format(cm[i, j]),\n",
    "                     horizontalalignment=\"center\",\n",
    "                     color=\"white\" if cm[i, j] > thresh else \"black\")\n",
    "        else:\n",
    "            plt.text(j, i, \"{:,}\".format(cm[i, j]),\n",
    "                     horizontalalignment=\"center\",\n",
    "                     color=\"white\" if cm[i, j] > thresh else \"black\")\n",
    "\n",
    "\n",
    "    plt.tight_layout()\n",
    "    plt.ylabel('True label')\n",
    "    plt.xlabel('Predicted label\\naccuracy={:0.4f}; misclass={:0.4f}'.format(accuracy, misclass))\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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n5TDvvKNWce8/W1vzvLLLX+nc++99NI55PNfzMMetnYuu/TSbLP1I/PEJz81K6ywQj74Xx/LcsstlyTZ761vyv985sC86S1vS5I8b6ed89FPfHrhvEFgbKm8wByc8Lu/5Orrbppy/3Gn/Dk3//PWJMlvz/hrVl91hVn7Nl3/gVllxeXys1+fM9s597n3EnntHtvlg587ZsrrXnjZ1Tnzz5fmjjvabNufvPX6Ofakc3PN9Tfl2htuzrEnnZunPGaDPHj1FXPehVfkymsGv6X839+cm2c/cZN5fLcA03P/1VbLJpsOqirLLrts1l1vvVx6ySWz9rfW8t1vHZGddtn1TueuvfY6edjD1k6SrPaAB2TllVfJlVdekSSzgktrLf+8+WZtMyzSqsb7MSrCC8wnL372o/PjE85OMlib/YNvfG7e/rHv3um4A175jHzyy8fmpptvmed7PGDlFXLx36+Z9fqSy6/NA1ZeIX+56Iqss9YqWXO1+2WxxWbkWU/YOGuset85XAlg/vjbX/+aM047LVts+e821hN+dXxWWXXVWSFlKqec/NvccsstechDHjpr274ve2ke+qAH5E9//GP2feWrZ23//ve+M6ud7OKLLpr/bwTohYUeXqrq2VXVqmq97vUmVfW0Cfu3raqt78b1b5wf44R5sevTHpnNNlgzHz/s2CTJy3feJj/+1Vm55PJrZzvuEeusngc/cOUc+fMz5uv9r73h5rz2/YfnKx96aY499A3526VX5Y477piv9wCY7MYbb8weuz0/H/zIv9u9kuRb3/xGdtr5zlWXif7vssvyspfumc8c8vnMmPHvH0cO/uyh+fMFF2fd9dabNR9mh6c/M2f98fycdMpp2W67J+Xle79kwbwhYOyNYs7Lbkl+1f33gCSbJNkiydHd/m2T3JjkxBGMDebZE7ZaN2/b66l5yt6fyC233pYk2eoRD85jNn1o9tl5m9zn3ktmiXstlhtv/lcuvOzqbL7Bmjn3qHdl8cVmZOX7LZsff/Z1eerLPjmte116xbXZZvN//yZz9VVWyPGn/jlJcvRxZ+bo485Mkrz0uY/J7bcLL8CCc+utt2aPXXfKzru+IDs++7mztt9222058vvfzfEnnjzluddff312es4zc8C73pMtt3rUnfYvtthied7zd8knPvZfeeGeL8mKK644a9+eL907/+8d+83f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",
      "text/plain": [
       "<Figure size 864x864 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from sklearn.metrics import confusion_matrix\n",
    "\n",
    "plot_confusion_matrix(cm = confusion_matrix(actual, test_pred), \n",
    "                      normalize    = False,\n",
    "                      target_names = np.unique(actual),\n",
    "                      title        = \"Confusion Matrix\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "      Attack     0.9993    0.9786    0.9888   1271344\n",
      "      Normal     0.6305    0.9808    0.7675     47374\n",
      "\n",
      "    accuracy                         0.9787   1318718\n",
      "   macro avg     0.8149    0.9797    0.8782   1318718\n",
      "weighted avg     0.9860    0.9787    0.9809   1318718\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import classification_report\n",
    "print(classification_report(actual, test_pred, digits=4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [],
   "source": [
    "th.save(model.state_dict(), 'ton-iot.binary.pt')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import classification_report\n",
    "print(classification_report(actual, test_pred, digits=2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "report = classification_report(actual, test_pred, digits=4, output_dict=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame(report).transpose()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df.to_csv('unsw_ton_iot_agg_report.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "th.save(model.state_dict(), 'unsw_ton_iot_agg_mul.pt')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
